/* Copyright (c) 2010 Kevin <cn0819@gmail.com>
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2010-09-09 15:30:56 $
 * $Rev: 2447 $
 *
 * Version 0.1
 */

 
(function($) {
    $.fn.ajaxTree = function(_opt){
        return $(this).each(function(){
			var opt = {
				url : '',
				data : null,
				multiple : false,
				click : null,
				success : null,
				check : null
			}
			opt = $.extend(opt, _opt);
			var tree = $(this);
			tree.empty().addClass('ajaxtree');

			click(tree);
			
			this.getTreeSelected = function(){
				return tree.find('li:has(>:checkbox:checked)');
			};
			
			this.reloadTree = function(node){
				click(node, true);
			};
			
			this.editTree = function(node,name,module,page,parameter,link,display_menu,display_list,order_by){
                                node.attr('module',module);
                                node.attr('page',page);
                                node.attr('parameter',parameter);
                                node.attr('link',link);
                                node.attr('display_menu',display_menu);
                                node.attr('display_list',display_list);
                                node.attr('order_by',order_by);
                                node.find('a:first').html(name);
                                node.find('span:first').html('[' + order_by + '][' + (display_menu == 'Y' ? '<font color="green">显示</font>':'<font color="red">隐藏</font>') + '][' + (display_list == 'Y' ? '<font color="green">显示</font>':'<font color="red">隐藏</font>') + ']');
			};
			
			this.removeTree = function(node){
				var ul = node.closest('ul');
				node.remove();
				if(ul.find('li').size() == 0){
					ul.parent().find('ins:first').removeClass().addClass('collapse');
					ul.remove();
				}
			};
			
			function click(node, force){
				force = force || false;
				if(node.data('loading') == 'yes') return;
				if(force){
					node.find('ul').remove();
				}
				if(node != tree){
					if(opt.click != null) opt.click(node);
					var ins = node.find('ins:first');
					if(!(ins.hasClass('expandable') || force)){
						return;
					}else if(ins.hasClass('close') || force){
						ins.toggleClass('close', false).toggleClass('open', true);
						if(node.find('ul').size() > 0){
							node.find('ul:first').show();
							if(opt.success != null) opt.success(node);
							return;
						}
					}else{
						ins.toggleClass('open', false).toggleClass('close', true);
						node.find('ul:first').hide();
						if(opt.success != null) opt.success(node);
						return;
					}
					
				}
				node.data('loading', 'yes').find('>:checkbox').after('<img src="images/simpletree/spinner.gif" />');
				var data = (opt.data != null) ? opt.data(node) : null;
				$.getJSON(opt.url, data, function(data){

					var checked = false;
					if(opt.multiple && node.find('.checkbox:first').hasClass('checked')){
						checked = true;
					}
					
					var html = mktree(data, checked);
					node.append(html);
					
					if(force && !node.hasClass('expandable') && data.length > 0){
						ins.removeClass('collapse').addClass('expandable open').click(function(){
							click( $(this).closest('li') );
						});
					}
					
					node.find('ul ins.expandable').click(function(){
						click( $(this).closest('li') );
					});
					node.find('ul .checkbox').click(function(){
						check($(this).closest('li'), $(this));
					});
					node.find('ul a').click(function(){
						$(this).prev().prev().click();
					});
					
					node.data('loading', null).find('>img').remove();
					if(opt.success != null) opt.success(node);
				});
			
			}
			
			function mktree(data, checked){
					var html = '<ul>';
					for(var i = 0; i < data.length; i++){
						var icon = 'close';
						if(data[i].status == 'open') icon = 'open';
						if(parseInt(data[i].child) > 0) icon += ' expandable';
						else icon = 'collapse';
						html += '<li id="node_' + data[i].id + '" module="' + data[i].module + '" page="' + data[i].page + '" parameter="' + data[i].parameter + '" link="' + data[i].link + '" display_menu="' + data[i].display_menu + '" display_list="' + data[i].display_list + '" order_by="' + data[i].order_by + '">';
						html += '<ins class="' + icon + '">&nbsp;</ins>';
						html += '<ins class="' + (checked ? 'checkbox checked' : 'checkbox') + '">&nbsp;</ins>';
						html += '<input type="checkbox" value="' + data[i].id + '" style="display:none;" /> ';
						html += '<a href="###">' + data[i].name + '</a> <span>[' + data[i].order_by + '][' + (data[i].display_menu == 'Y' ? '<font color="green">显示</font>':'<font color="red">隐藏</font>') + '][' + (data[i].display_list == 'Y' ? '<font color="green">显示</font>':'<font color="red">隐藏</font>') + ']</span>';
						if(data[i].children){
							html += mktree(data[i].children, checked);
						}
						html += '</li>';
					}
					html += '</ul>';
					return html;
			}
			
			function check(node, checkbox){
				var input = checkbox.next();
				var checked = !checkbox.hasClass('checked');
				checkbox.toggleClass('checked', checked);
				input.attr('checked', checked);

				if(opt.multiple){
					node.find('ul .checkbox').toggleClass('checked', checked);
					node.find('ul :checkbox').attr('checked', false);
					
					checkParent(node);
					checkChildren(tree.find('>ul>li'));
					
				}else{
					tree.find(':checkbox').not(input).attr('checked', false);
					tree.find('.checkbox').not(checkbox).toggleClass('checked', false);
				}
				if(opt.check != null) opt.check(node);
			}
			
			function checkParent(node){
				var parentUL = node.closest('ul');
				if(parentUL.parent().get(0) == tree.get(0)) return;
				var checkbox_nums = parentUL.find('>li>:checkbox').size();
				var checkbox_checked_nums = parentUL.find('>li>.checked').size();
				var _checked = checkbox_nums == checkbox_checked_nums ? true : false;
				parentUL.closest('li').find(':checkbox:first').attr('checked', _checked);
				parentUL.closest('li').find('.checkbox:first').toggleClass('checked', _checked);
				
				if(_checked) parentUL.find('>li>:checkbox').attr('checked', false);
				
				checkParent(parentUL.parent());
				
			}
			
			function checkChildren(node){
				if(!node.find('.checkbox:first').hasClass('checked')){
					node.find('>ul>li>:checkbox').each(function(){
						$(this).attr('checked', $(this).prev().hasClass('checked'));
						checkChildren($(this).parent());
					});
				}
			}
			
		});
	};
			
	$.fn.getTreeSelected = function(){
		return this.get(0).getTreeSelected();
	};
	
	$.fn.reloadTree = function(node){
		return $(this).each(function(){
			this.reloadTree(node);
		});
	};
	
	$.fn.editTree = function(node,name,module,page,parameter,link,display_menu,display_list,order_by){
		return $(this).each(function(){
			this.editTree(node,name,module,page,parameter,link,display_menu,display_list,order_by);
		});
	};
	
	$.fn.removeTree = function(node){
		return $(this).each(function(){
			this.removeTree(node);
		});
	};
})(jQuery);